package com.itools.core.init;

import com.itools.core.rbac.param.initDB.InitDBInsertParam;
import com.itools.core.rbac.param.initDB.InitDBQueryParam;
import com.itools.core.rbac.param.initDB.InitDBResult;
import com.itools.core.utils.StringUtils;
import org.apache.ibatis.io.Resources;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @Author XUCHANG
 * @description:
 * @Date 2020/9/10 15:33
 */
@Component
@Order(value = 1)
public class MyDmlApplicationRunner implements ApplicationRunner {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private Environment environment;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        if (!environment.containsProperty("initDB.is-use")){
            return;
        }
        Boolean isUse = environment.getProperty("initDB.is-use",Boolean.class);
        if (!isUse){
            return;
        }
        DataSource dataSource = applicationContext.getBean(DataSource.class);
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
        } catch (SQLException e) {
            logger.info("数据源连接失败",e);
        }
        String dmlProperty = environment.getProperty("initDB.dml");
        String[] files = dmlProperty.split(",");
        InitDbService initDBService = applicationContext.getBean(InitDbService.class);
        MyScriptRunner runner = new MyScriptRunner(connection,getInitDBMap(initDBService));
        try {
            List<InitDBInsertParam> dbInsertParams = new ArrayList<>();
            for (String file : files){
                logger.info("开始执行{}脚本文件",file);
                Reader dmlResourceAsReader = Resources.getResourceAsReader(file);
                runner.setImplemented(true);
                runner.setDelimiter(environment.getProperty("initDB.delimiter"));
                runner.setThrowWarning(true);
                List<String> result = runner.runLineScript(dmlResourceAsReader);

                for (String sql : result){
                    if (StringUtils.isEmpty(sql)){
                        continue;
                    }
                    InitDBInsertParam initDBInsertParam = new InitDBInsertParam();
                    initDBInsertParam.setContent(sql);
                    initDBInsertParam.setEnv(environment.getProperty("initDB.env"));
                    initDBInsertParam.setType("dml");
                    logger.info("DML：执行了"+sql);
                    initDBInsertParam.setVersion(environment.getProperty("initDB.version"));
                    dbInsertParams.add(initDBInsertParam);
                }
                logger.info("脚本{}执行成功",file);
            }
            initDBService.multipartInsert(dbInsertParams);
        } catch (IOException e) {
            logger.error("Resources获取失败",e);
        }
        logger.info("DML脚本执行完成");
    }
    private Map<String,String> getInitDBMap(InitDbService initDBService){
        Map<String,String> result  = new HashMap<>();
        InitDBQueryParam initDBQueryParam = new InitDBQueryParam();
        initDBQueryParam.setEnv(environment.getProperty("initDB.env"));
//        initDBQueryParam.setVersion(environment.getProperty("initDB.version"));
        initDBQueryParam.setType("dml");
        List<InitDBResult>  resultList = initDBService.query(initDBQueryParam);
        for (InitDBResult initDBResult : resultList){
            result.put(initDBResult.getId(),replaceBlank(initDBResult.getContent()));
        }
        return result;
    }
    private static String replaceBlank(String str) {
        String dest = "";
        if (str!=null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }
}
